package cqrtplm.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hustcad.plm.basic.util.TyplmEntityBaseUtil;
import com.hustcad.plm.pdm.iba.service.TyplmAttributeValueService;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.entity.org.UserDO;
import com.ty.basic.response.ResponseResult;
import com.ty.basic.service.snow.SnowflakeIdComponent;
import com.ty.basic.session.TyAccountContext;
import com.ty.basic.vo.AttributeVO;
import cqrtplm.constant.RTPlmConstant;
import cqrtplm.dto.RTDescribeInformationDTO;
import cqrtplm.dto.RTDescribeInformationlDTO;
import cqrtplm.entity.RTDescribeInformationDO;
import cqrtplm.info.RuleInfo;
import cqrtplm.mapper.RTEngraveMapper;
import cqrtplm.service.RTEngraveService;
import cqrtplm.vo.ModuleVO;
import cqrtplm.vo.RTEngraveDemandStatusVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cqrtplm.constant.RTErrorCodeEnum.ENGRAVE_NOT_EXIST;

@Service
@Slf4j
@Transactional
public class RTEngraveServiceImpl implements RTEngraveService {

    private final List<RuleInfo> rules;

    @Autowired
    public RTEngraveServiceImpl(List<RuleInfo> rules) {
        this.rules = rules;
    }

    @Resource
    private RTEngraveMapper rtEngraveMapper;
    @Resource
    private SnowflakeIdComponent snowflakeIdComponent;
    @Resource
    private TyplmAttributeValueService typlmAttributeValueService;


    @Override
    public ResponseResult<RTDescribeInformationDTO> queryEngraveDetail() {
        RTDescribeInformationDTO rtDescribeInformation = new RTDescribeInformationDTO();
        List<BigInteger> partOids=rtEngraveMapper.selectIbaAttr("ProductSpecification");
        Map<String, List<AttributeVO>> ibaMaps = typlmAttributeValueService.getIbaAttrValueByOidAndKeys(
                partOids,
                TableTypeConstrant.TY_PART_OTYPE,
                Collections.singletonList(RTPlmConstant.PRODUCTTYPE));
        List<String> models = ibaMaps.values().stream()
                .flatMap(List::stream)
                .map(AttributeVO::getAttributeValue)
                .filter(attributeValue -> StringUtils.isNotEmpty(String.valueOf(attributeValue)))
                .distinct()
                .collect(Collectors.toList());
        List<ModuleVO> moduleVOS = batchQueryModuleVO(partOids,800);
        rtDescribeInformation.setModels(models);
        rtDescribeInformation.setRules(rules);
        rtDescribeInformation.setModuleList(moduleVOS);
        return ResponseResult.success(rtDescribeInformation);
    }
    private List<ModuleVO> batchQueryModuleVO(List<BigInteger> partOids, int batchSize) {
        List<ModuleVO> allModuleVOS = new ArrayList<>();

        for (int i = 0; i < partOids.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, partOids.size());
            List<BigInteger> subPartOids = partOids.subList(i, endIndex);
            List<ModuleVO> batchResult = rtEngraveMapper.selectDevCodeAndProductTypeByPartOid(subPartOids);
            allModuleVOS.addAll(batchResult);
        }
        allModuleVOS = allModuleVOS.stream()
                .distinct()
                .collect(Collectors.toList());

        return allModuleVOS;
    }

    @Override
    public ResponseResult addEngraveDetails(RTDescribeInformationDO rtDescribeInformationDO) {
        if (ObjectUtil.isEmpty(rtDescribeInformationDO)) {
            return ResponseResult.fail("500", "参数错误");
        }

        // 提取拼接规则方法，避免重复逻辑
        String ruleList = buildRuleList(rtDescribeInformationDO);

        try {
            boolean exists = rtEngraveMapper.selectByRuleList(ruleList);
            if (exists) {
                return ResponseResult.fail("500", "此规则已存在");
            }
        } catch (Exception e) {
            // 增加异常处理，避免 mapper 查询异常导致服务崩溃
            return ResponseResult.fail("500", "查询规则失败");
        }

        rtDescribeInformationDO.setOid(snowflakeIdComponent.getInstance().nextId());
        TyplmEntityBaseUtil.fillCommonFieldForCreate(rtDescribeInformationDO);
        UserDO user = TyAccountContext.getUser();

        rtDescribeInformationDO.setStopUserName(user.getFullname());
        rtDescribeInformationDO.setCreateUserCname(user.getFullname());
        rtDescribeInformationDO.setCreatestamp(new Date());

        if (ObjectUtil.isNull(rtDescribeInformationDO.getStopFlag())) {
            rtDescribeInformationDO.setStopFlag(BigInteger.valueOf(0));
        }

        // 设置 rulelist 字段
        rtDescribeInformationDO.setRulelist(ruleList);

        rtEngraveMapper.insertEngraveDetails(rtDescribeInformationDO);
        return ResponseResult.success(rtDescribeInformationDO);
    }

    /**
     * 构建规则字符串，用于判重
     */
    private String buildRuleList(RTDescribeInformationDO rtDescribeInformationDO) {
        StringBuilder sb = new StringBuilder();

        appendRuleIfValid(sb, rtDescribeInformationDO.getRow1Rule1(), rtDescribeInformationDO.getRow1Rule2());
        appendRuleIfValid(sb, rtDescribeInformationDO.getRow2Rule1(), rtDescribeInformationDO.getRow2Rule2());
        appendRuleIfValid(sb, rtDescribeInformationDO.getRow3Rule1(), rtDescribeInformationDO.getRow3Rule2());
        appendRuleIfValid(sb, rtDescribeInformationDO.getRow4Rule1(), rtDescribeInformationDO.getRow4Rule2());
        appendRuleIfValid(sb, rtDescribeInformationDO.getRow5Rule1(), rtDescribeInformationDO.getRow5Rule2());

        return sb.toString();
    }

    /**
     * 如果两个规则字段都不为 null 且不为空字符串，则拼接
     */
    private void appendRuleIfValid(StringBuilder sb, String rule1, String rule2) {
        if (StrUtil.isNotBlank(rule1) && StrUtil.isNotBlank(rule2)) {
            sb.append(rule1).append(rule2);
        }
    }


    @Override
    @Transactional
    public ResponseResult stopEngraveDetail(RTDescribeInformationDO rtDescribeInformationDO) {
        RTDescribeInformationDO rtDescribeInformation = rtEngraveMapper.selectByOid(rtDescribeInformationDO.getOids());
        if (ObjectUtil.isNotEmpty(rtDescribeInformation)) {
            ZoneId zone = ZoneId.of("Asia/Shanghai");
            long now = LocalDateTime.now().atZone(zone).toInstant().toEpochMilli();
            rtDescribeInformation.setUpdatestamp(new Date(now));
            if (rtDescribeInformation.getStopFlag().equals(new BigInteger("0")) ) {
                rtDescribeInformation.setStopFlag(BigInteger.valueOf(1));
                rtDescribeInformation.setStopTime(new Timestamp(now));
            } else {
                rtDescribeInformation.setStopFlag(BigInteger.valueOf(0));  //0 启用 1 停用
                rtDescribeInformation.setStartTime(new Timestamp(now));
            }
            TyplmEntityBaseUtil.fillCommonFieldForCreate(rtDescribeInformation);
            rtEngraveMapper.updateByOid(rtDescribeInformation);
            return ResponseResult.success();
        }
        return ResponseResult.fail(ENGRAVE_NOT_EXIST);
    }


    @Override
    public PageInfo<RTDescribeInformationDO> searchByDescribeInformationCode(String describeInformationCode,String engraveName, int pageNum, int pageSize,String row1Rule1,String row2Rule1,String row3Rule1,String row4Rule1,String row5Rule1) {
        PageHelper.startPage(pageNum, pageSize);
        List<RTDescribeInformationDO> rtDescribeInformationList =  rtEngraveMapper.queryByDescribeInformationCode(describeInformationCode,engraveName,row1Rule1,row2Rule1,row3Rule1,row4Rule1,row5Rule1);
        return new PageInfo<>(rtDescribeInformationList);
    }

    @Override
    public PageInfo<RTEngraveDemandStatusVO> queryEngraveDemandStatus(String engraveContent, int page, int pageSize) {

        if (StringUtils.isBlank(engraveContent)) {
            return new PageInfo<>();
        }
        PageHelper.startPage(page, pageSize);
        try {
            List<RTEngraveDemandStatusVO> resultList = rtEngraveMapper.selectByEngraveCode(engraveContent);
            PageInfo<RTEngraveDemandStatusVO> pageInfo = new PageInfo<>(resultList);
            return pageInfo;
        } catch (Exception e) {
            throw new RuntimeException("查询需求状态表失败", e);
        }
    }

    @Override
    public ResponseResult updateStatusRequirementtable(RTDescribeInformationlDTO rtDescribeInformationlDTO) {
        TyplmEntityBaseUtil.fillCommonFieldForUpdate(rtDescribeInformationlDTO);
//        int i = rtEngraveMapper.updateByOidTwo(rtDescribeInformationlDTO);
//        if (i <= 0) {
//            return ResponseResult.fail("500", "更新失败");
//        }

        //拼接规则
            StringBuffer stringBuffer = new StringBuffer();
            if (StrUtil.isNotBlank(rtDescribeInformationlDTO.getRow1Rule1())){
                stringBuffer.append(rtDescribeInformationlDTO.getRow1Rule1());
            }
            if (StrUtil.isNotBlank(rtDescribeInformationlDTO.getRow2Rule1())){
                if (stringBuffer.length() > 0) {
                    stringBuffer.append("|||");
                }
                stringBuffer.append(rtDescribeInformationlDTO.getRow2Rule1());
            }
            if (StrUtil.isNotBlank(rtDescribeInformationlDTO.getRow3Rule1())){
                if (stringBuffer.length() > 0) {
                    stringBuffer.append("|||");
                }
                stringBuffer.append(rtDescribeInformationlDTO.getRow3Rule1());
            }
            if (StrUtil.isNotBlank(rtDescribeInformationlDTO.getRow4Rule1())){
                if (stringBuffer.length() > 0) {
                    stringBuffer.append("|||");
                }
                stringBuffer.append(rtDescribeInformationlDTO.getRow4Rule1());
            }
            if (StrUtil.isNotBlank(rtDescribeInformationlDTO.getRow5Rule1())){
                if (stringBuffer.length() > 0) {
                    stringBuffer.append("|||");
                }
                stringBuffer.append(rtDescribeInformationlDTO.getRow5Rule1());
            }
            //打刻编码
            String engraveCode = rtDescribeInformationlDTO.getEngraveCode();

        int i2 = rtEngraveMapper.updateOldStatusCodeAndOldStatusCode(rtDescribeInformationlDTO.getStatuscode());
        if (i2 <= 0) {
            return ResponseResult.fail("500", "更新失败");
        }
        // 获取当前登录用户信息
        UserDO user = TyAccountContext.getUser();
        int i1 = rtEngraveMapper.updateValueByCode(engraveCode
                , rtDescribeInformationlDTO.getStatuscode(), String.valueOf(stringBuffer),user.getName(), user.getOid());
        if (i1 <= 0){
            return ResponseResult.fail("500", "更新失败");
        }
        return ResponseResult.success();
    }

    @Override
    public void deleteEngraveDetail(List<BigInteger> oIds) {
        rtEngraveMapper.deleteEngraveDetailById(oIds);
    }

    @Override
    public ResponseResult searchByOids(List<String> oids) {
        if (ObjectUtil.isEmpty(oids)) {
            return ResponseResult.fail("500", "参数为空");
        }

        List<RTDescribeInformationDO> allResults = new ArrayList<>();
        int batchSize = 1000;

        for (int i = 0; i < oids.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, oids.size());
            List<String> batchOids = oids.subList(i, endIndex);
            List<RTDescribeInformationDO> batchResults = rtEngraveMapper.selectByOids(batchOids);
            allResults.addAll(batchResults);
        }

        return ResponseResult.success(allResults);
    }


    @Override
    public ResponseResult searchEuemissionsnoByModel(String model) {
        String[] split = model.split(",");
        ArrayList<String> list = new ArrayList<>(split.length);
        Collections.addAll(list, split);
        return  ResponseResult.success(rtEngraveMapper.searchEuemissionsnoByModel(list));
    }
}
